<script setup>
import MenuApi from '@/api/menu.js'
import { menuType } from '@/enums/menuEnums.js'
import { sys_yes_no } from '@/enums/dict.js'


const menuFormRef = ref(null);

const menuTableData = ref([])
const dialog = reactive({
  visible: false,
  title: ''
})

// 初始菜单表单数据
const initialMenuFormData = ref({
  id: undefined,
  parentId: '0',
  visible: 1,
  sort: 1,
  type: menuType.MENU, // 默认菜单
  alwaysShow: sys_yes_no.YES,
  keepAlive: sys_yes_no.YES,
  params: ''
})

/*父级菜单列表*/
const menuOptions = ref([])
/*组件列表，写死在后端的*/
const components = ref([])
// 菜单表单数据
const formData = ref({ ...initialMenuFormData.value })

/**
 * 菜单类型对应的菜单项
 */
const dialogTypeConfig = {
  [menuType.DIR]: {
    path: true,
    visible: true,
    alwaysShow: true,
    sort: true,
    icon: true,
    redirect: true
  },
  [menuType.MENU]: {
    path: true,
    component: true,
    params: true,
    visible: true,
    alwaysShow: true,
    keepAlive: true,
    sort: true,
    icon: true,
    perm: true
  },
  [menuType.PERMISSION]: {
    sort: true,
    perm: true
  },
  [menuType.LINK]: {
    link: true,
    visible: true,
    sort: true,
    icon: true
  }
}
const currDialogType = computed(() => {
  return dialogTypeConfig[formData.value.type]
})

// 表单验证规则
const rules = reactive({
  parentId: [{ required: true, message: '请选择顶级菜单', trigger: 'blur' }],
  name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }],
  path: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
  component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
  visible: [{ required: true, message: '请输入路由路径', trigger: 'blur' }]
})


const getList = () => {
  MenuApi.menus().then(res => {
    menuTableData.value = res.data
  })
}
const rest = () => {
  formData.value = { ...initialMenuFormData.value }
}
/**
 * 打开表单弹窗
 *
 * @param parentId 父菜单ID
 * @param menuId 菜单ID
 */
const handleDialogOpen = (parentId, menuId) => {
  rest()
  MenuApi.options()
    .then(({ data }) => {
      menuOptions.value = [{ id: '0', name: '顶级菜单', children: data }]
    })
    .then(() => {
      MenuApi.components().then(({ data }) => {
        components.value = data
      })
    })
    .then(() => {
      dialog.visible = true
      if (menuId) {
        dialog.title = '编辑菜单'
        MenuApi.getInfo(menuId).then(({ data }) => {
          formData.value = { ...data }
          formData.value = data
        })
      } else {
        dialog.title = '新增菜单'
        formData.value.parentId = parentId+''
      }
    })
}

//   删除菜单
const handleDelete=(menuId)=> {
  if (!menuId) {
    ElMessage.warning("请勾选删除项");
    return false;
  }
  ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
  .then(() => {
    MenuApi.deleteMenu(menuId).then(() => {
      ElMessage.success("删除成功");
      getList();
    });
  })
  .catch(() => ElMessage.info("已取消删除"));
}


// 关闭弹窗
const closeDialog = () => {
  dialog.visible = false
  // menuFormRef.value.resetFields();
  // menuFormRef.value.clearValidate();
  formData.value.id = undefined
}

const submitForm = () => {
  // MenuApi.addMenu(formData.value).then(() => {
  //   getList()
  //   dialog.visible = false
  // })
  menuFormRef.value.validate((isValid) => {
    if (isValid) {
      const menuId = formData.value.id
      if (menuId) {
        MenuApi.editMenu(formData.value).then(() => {
          ElMessage.success('修改成功')
          closeDialog()
          getList()
        })
      } else {
        MenuApi.addMenu(formData.value).then(() => {
          ElMessage.success('新增成功')
          closeDialog()
          getList()
        })
      }
    }
  })
}

getList()
</script>

<template>
  <div class="app-container">
    <el-card shadow="never" class="table-container">
      <template #header>
        <el-button
          v-hasPerm="['sys:menu:add']"
          type="success"
          @click="handleDialogOpen(0)"
        >
          <template #icon>
            <i-ep-plus />
          </template>
          新增
        </el-button
        >
      </template>
      <el-table
        :data="menuTableData"
        highlight-current-row
        row-key="id"
        :tree-props="{
          children: 'children',
          hasChildren: 'hasChildren',
        }"
      >
        <el-table-column label="菜单名称" min-width="200">
          <template #default="scope">
            <template
              v-if="scope.row.icon && scope.row.icon.startsWith('el-icon')"
            >
              <el-icon style="vertical-align: -0.15em">
                <component :is="scope.row.icon.replace('el-icon-', '')" />
              </el-icon>
            </template>
            <template v-else-if="scope.row.icon">
              <svg-icon :icon-class="scope.row.icon" />
            </template>
            <template v-else>
              <svg-icon icon-class="menu" />
            </template>
            {{ scope.row.name }}
          </template>
        </el-table-column>

        <el-table-column label="类型" align="center" width="80" prop="path">
          <template #default="scope">
            {{ scope.row.type }}
          </template>
        </el-table-column>

        <el-table-column
          label="路由路径"
          align="left"
          width="150"
          prop="path"
        />

        <el-table-column
          label="组件路径"
          align="left"
          width="150"
          prop="component"
        />

        <el-table-column
          label="权限标识"
          align="center"
          width="200"
          prop="perm"
        />

        <el-table-column label="状态" align="center" width="80">
          <template #default="scope">
            <el-tag v-if="scope.row.visible === 1" type="success">显示</el-tag>
            <el-tag v-else type="info">隐藏</el-tag>
          </template>
        </el-table-column>

        <el-table-column label="排序" align="center" width="80" prop="sort" />

        <el-table-column fixed="right" align="center" label="操作" width="220">
          <template #default="scope">
            <el-button
              v-hasPerm="['sys:menu:add']"
              type="primary"
              link
              size="small"
              @click.stop="handleDialogOpen(scope.row.id)"
            >
              <i-ep-plus />
              新增
            </el-button>
            <el-button
              v-hasPerm="['sys:menu:edit']"
              type="primary"
              link
              size="small"
              @click.stop="handleDialogOpen(undefined, scope.row.id)"
            >
              <i-ep-edit />
              编辑
            </el-button>
            <el-button
              v-hasPerm="['sys:menu:delete']"
              type="danger"
              link
              size="small"
              @click.stop="handleDelete(scope.row.id)"
            >
              <i-ep-delete />
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-dialog
      v-model="dialog.visible"
      :title="dialog.title"
      destroy-on-close
      append-to-body
      width="1000px"
    >
      <el-form
        ref="menuFormRef"
        :model="formData"
        :rules="rules"
        label-width="160px"
      >
        <el-form-item label="父级菜单" prop="parentId">
          <el-tree-select
            :props="{label: 'name', children: 'children'}"
            v-model="formData.parentId"
            placeholder="选择上级菜单"
            :data="menuOptions"
            value-key="id"
            row-key="id"
            filterable
            check-strictly
            :render-after-expand="false"
          />
        </el-form-item>

        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="formData.name" placeholder="请输入菜单名称" />
        </el-form-item>

        <el-form-item label="菜单类型" prop="type">
          <el-radio-group
            v-model="formData.type"
          >
            <el-radio :value="menuType.DIR">目录</el-radio>
            <el-radio :value="menuType.MENU">菜单</el-radio>
            <el-radio :value="menuType.PERMISSION">按钮</el-radio>
            <el-radio :value="menuType.LINK">外链</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 路由路径 -->
        <el-form-item
          v-if="currDialogType.path"
          label=""
          prop="path"
        >
          <template #label>
            <div>
              路由路径
              <el-tooltip placement="bottom" effect="light">
                <template #content>
                  定义应用中不同页面对应的 URL 路径，目录需以 /
                  开头，菜单项不用。例如：系统管理目录
                  /system，系统管理下的用户管理菜单 user。
                </template>
                <i-ep-QuestionFilled class="inline-block" />
              </el-tooltip>
            </div>
          </template>
          <el-input v-model="formData.path" placeholder="user" />
        </el-form-item>

        <!-- 组件 -->
        <el-form-item v-if="currDialogType.component" label="组件名称" prop="name">
          <el-select v-model="formData.componentId" placeholder="请选择" style="width: 240px">
            <el-option
              v-for="item in components"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item
          v-if="currDialogType.visible"
          prop="visible"
          label="显示状态"
        >
          <el-radio-group v-model="formData.visible">
            <el-radio :value="1">显示</el-radio>
            <el-radio :value="0">隐藏</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item
          v-if="currDialogType.alwaysShow"
        >
          <template #label>
            <div>
              始终显示
              <el-tooltip placement="bottom" effect="light">
                <template #content>
                  选择“是”，即使目录或菜单下只有一个子节点，也会显示父节点。<br />
                  选择“否”，如果目录或菜单下只有一个子节点，则只显示该子节点，隐藏父节点。<br />
                  如果是叶子节点，请选择“否”。
                </template>
                <i-ep-QuestionFilled class="inline-block" />
              </el-tooltip>
            </div>
          </template>

          <el-radio-group v-model="formData.alwaysShow">
            <el-radio :value="1">是</el-radio>
            <el-radio :value="0">否</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item
          v-if="currDialogType.keepAlive"
          label="页面缓存"
        >
          <el-radio-group v-model="formData.keepAlive">
            <el-radio :value="1">开启</el-radio>
            <el-radio :value="0">关闭</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item
          v-if="currDialogType.sort"
          label="排序" prop="sort">
          <el-input-number
            v-model="formData.sort"
            style="width: 100px"
            controls-position="right"
            :min="0"
          />
        </el-form-item>

        <!-- 权限标识 -->
        <el-form-item
          v-if="currDialogType.perm"
          label="权限标识"
          prop="perm"
        >
          <el-input v-model="formData.perm" placeholder="sys:user:add" />
        </el-form-item>

        <el-form-item
          v-if="currDialogType.icon"
          label="图标"
          prop="icon"
        >
          <!-- 图标选择器 -->
          <icon-select v-model="formData.icon" />
        </el-form-item>

        <el-form-item
          v-if="currDialogType.redirect"
          label="跳转路由"
        >
          <el-input v-model="formData.redirect" placeholder="跳转路由" />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="closeDialog">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>

</style>
